<template>
  <!--  地图  -->
  <div class="map-box box-shadow">
    <div id="mapboxgl-box"></div>
  </div>
  <div class="form-box box-shadow">
    <div class="set-header">
      <span>所选单元-{{cellInfo.cellName}}</span>
    </div>
    <div class="set-form">
      <span>标准设置</span>
      <div class="standard">
        <div class="left-form">
          <a-form
              :model="tampNormFormState"
              :wrapperCol="{span:24}"
              layout="inline">
            <a-form-item label="设计搅拌次数">
              <a-input-number v-model:value="norm.mixCount" :min="0"/>
            </a-form-item>
            <a-form-item label="设计深度(m)">
              <a-input-number v-model:value="norm.depth" :min="0"/>
            </a-form-item>
            <a-form-item label="设计喷浆次数">
              <a-input-number v-model:value="norm.shootCount" :min="0"/>
            </a-form-item>
            <a-form-item label="倾斜度阈值">
              <a-input-number v-model:value="norm.gradient" :min="0"/>
            </a-form-item>
            <a-form-item label="搅拌升降速度(m/min)" class="item-width">
              <a-input-number v-model:value="norm.mixSpeed" :min="0"/>
            </a-form-item>
            <a-form-item label="喷浆升降速度(m/min)" class="item-width">
              <a-input-number v-model:value="norm.shootSpeed" :min="0"/>
            </a-form-item>
          </a-form>
        </div>
        <div class="right-table">
          <span>喷浆停留位置和时间：</span>
          <a-table
              :data-source="norm.shotcret"
              :scroll="{y:'120px'}"
              :pagination="false">
            <a-table-column
                title="序号"
                width="65px"
                data-index="order"/>
            <a-table-column
                title="停留位置"
                data-index="staySite">
              <template #default="{text, record, index}">
                <a-select
                    v-model:value="record.staySite">
                  <a-select-option
                      v-for="cement in cementDict.dict"
                      :key="cement.key" :value="cement.key">
                    {{cement.value}}
                  </a-select-option>
                </a-select>
              </template>
            </a-table-column>
            <a-table-column
                title="喷浆时间(s)"
                width="100px"
                data-index="shootTime">
              <template #default="{text,record}">
                <a-input-number v-model:value="record.shootTime" style="width: 100px"/>
              </template>
            </a-table-column>
            <a-table-column
                title="删除"
                width="80px">
              <template #default="{text,record,index}">
                <div class="table-icon-box">
                  <div @click="removeNorm(index)" style="width:100%">
                    <DeleteOutlined/>
                  </div>
                </div>
              </template>
            </a-table-column>
          </a-table>
          <div class="button-box">
            <a-button @click="addVNorm" type="primary">新增</a-button>
            <a-button @click="setNorm" type="primary">保存</a-button>
          </div>
        </div>
      </div>
      <span>单元范围设置</span>
      <a-form
          :labelCol="{style: 'width: 120px'}"
          :wrapperCol="{span:24}"
          layout="inline">
        <a-form-item label="坐标系">
          <a-select
              v-model:value="coordinateType">
            <a-select-option
                v-for="coordinate in coordinateDict.dict"
                :key="coordinate.key" :value="coordinate.key">
              {{coordinate.value}}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item class="button-box">
          <a-button @click="openFileModal('uploadBorderFile')" type="primary">导 入
            <input
                id="uploadBorderFile"
                @change="readBorderFile(cellInfo.cellId)"
                accept=".txt"
                style="position:absolute;width:0;height:0;opacity:0"
                type="file"/>
          </a-button>
          <a-button @click="getBorder(coordinateType,cellInfo.cellId,()=>{showBorderModal = true})" :disabled="cellInfo.cellId<0" type="primary">显 示</a-button>
        </a-form-item>
      </a-form>
      <span>设计点设置</span>
      <a-form
          :model="cementDesignPointForm"
          :labelCol="{style: 'width: 120px'}"
          :wrapperCol="{span:24}"
          layout="inline">
        <a-form-item label="设计点间距">
          <a-input-number v-model:value="cementDesignPointForm.distance" :min="0" :step="0.1" style="width: 177px"/>
        </a-form-item>
        <a-form-item class="right-item">
          <input
              id="uploadPointFile1"
              @change="readPointFile(cellInfo.cellId,'uploadPointFile1')"
              accept=".txt"
              style="position:absolute;width:0;height:0;opacity:0;"
              type="file"/>
          <a-button @click="openFileModal('uploadPointFile1')" :disabled="cellInfo.cellId<0" type="primary">自定义设计点</a-button>
          <a-button @click="buildCementDesignPoint(cellInfo.cellId)" :disabled="cellInfo.cellId<0" type="primary">生成设计点</a-button>
          <a-button @click="downloadPointFile(cellInfo.cellId)" :disabled="cellInfo.cellId<0" type="primary">下载设计点</a-button>
        </a-form-item>
      </a-form>
    </div>
  </div>
  <SModal
      title="边界坐标"
      :width="372"
      :height="300"
      :isShow="showBorderModal"
      @closed="() => {showBorderModal = false}">
    <div class="add-modal-box">
      <a-table
          style="flex: 1"
          :data-source="coordinateType==1?abBorder:wgsBorder"
          :bordered="false"
          :scroll="{y: '180px' }"
          :pagination="false"
          :locale="{ emptyText: '暂无数据' }"
          :rowKey="(record) => record.lon"
      >
        <a-table-column :title="coordinateType==1?'P坐标':'经度'" data-index="lon">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
        <a-table-column :title="coordinateType==1?'H坐标':'纬度'" data-index="lat">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
      </a-table>
    </div>
  </SModal>
</template>

<script lang="ts">
import {defineComponent, onBeforeUnmount, onMounted, reactive, ref, toRefs, watch} from "vue"
import coordinateDict from "@/dicts/coordinateDict";
import cementDict from "@/dicts/cementDict";
import SModal from "@/components/SModal/index.vue";
import mapboxgl, {AnyLayer, Sources} from "mapbox-gl";
import redLine from "@/assets/data/redLine";
import KindEnum from "@/enums/kindEnum";
import config from "@/config/index"
import axios from "@/utils/axios"
import { EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import qs from "qs";
import {message} from "ant-design-vue";

interface MapLayerRequestInfo{
  craft: string | null;
  cellId: number | null;
  type: string | null;
}

interface ShotcretNorm{
  order: number,
  staySite: number| null,
  shootTime: number | null,
}

class Norm{
  cellId = -1
  shotcret = new Array<ShotcretNorm>()
  mixCount: number | null = null // 设计搅拌次数
  shootCount: number | null = null // 设计喷浆次数
  mixSpeed: number | null = null // 搅拌升降速度
  shootSpeed: number | null = null // 喷浆升降速度
  depth: number | null = null // 设计深度
  gradient: number | null = null // 倾斜度
}

class CoordinateForm{
  cellId: number = -1
  count: number = 0
  first = new Array<number>()
  second = new Array<number>()
}

class CementDesignPointForm{
  cellId: number = -1
  distance: number | undefined
}

export default defineComponent({
  setup(props) {
    const coordinateTypeFormState = ref(new CoordinateForm())
    const coordinateType = ref(1)
    const showBorderModal = ref(false)
    const border:any = reactive({
      abBorder:[],
      wgsBorder:[]
    })
    const norm = ref(new Norm())
    const cementDesignPointForm = ref(new CementDesignPointForm())

    let maps:any
    const initMap = ()=>{
      mapboxgl.accessToken = config.map.accessToken
      let mapSource:Sources = {
        google: {
          type: "raster",
          tiles: [
            config.map.baseLayer1URL,
          ],
          tileSize: 256,
        },
      }
      let layers:AnyLayer[] = [
        {
          id: "google-tiles1",
          type: "raster",
          source: "google",
        },
      ]
      maps = {
        map:new mapboxgl.Map({
          container: "mapboxgl-box",
          style: {
            version: 8,
            sources: mapSource,
            layers: layers,
          },
          minZoom: 5,
          center: config.map.center,
          zoom: 13,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }

      maps.map.on("load",()=>{
        maps.map.addLayer({
          id: "satellite",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.baseLayer2URL],
          },
        })
        maps.map.addLayer({
          id: "satellite2",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.airUrl],
          },
        })
        maps.map.addSource("readLineSource",{type:"geojson",data:redLine})
        maps.map.addLayer({
          id: "readLineLayer",
          type: "line",
          source: "readLineSource",
          layout: {},
          paint: {
            "line-color":"#ff0000",
            "line-width":2,
            "line-opacity":1
          },
        })
      })
    }
    // 喷浆停留位置和时间新增数据
    const addVNorm = ()=>{
      norm.value.shotcret.push({
        order: norm.value.shotcret.length,
        staySite: 0,
        shootTime: null,
      })
    }
    // 喷浆停留位置和时间删除数据
    const removeNorm = (index:number)=>{
      // 移除当前列,遍历数据重新赋值order
      norm.value.shotcret.splice(index,1)
      for(let i = 0;i < norm.value.shotcret.length;i++){
        norm.value.shotcret[i].order = i
      }
    }
    // 查找施工单元标准  cement-修改接口---已修改
    const getNorm = (cellId:number)=>{
      axios.post("/cement/findCellParameterByCellId",{cellId:cellId}).then((res:any)=>{
        norm.value = new Norm()
        norm.value.cellId = cellId
        if(res.success && res.data){
          Object.assign(norm.value,res.data)
        }else if(res.success && !res.data){
          message.info("暂未录入标准")
        }else{
          message.info("获取标准失败")
        }
      })
    }
    // 新增修改施工单元标准  cement-修改接口---已修改
    const setNorm = ()=>{
      axios.post("/cement/saveCellParameter",norm.value).then((res:any)=>{
        if(res.success){
          message.info("保存成功")
        }else{
          message.info("保存失败")
        }
      })
    }
    // 打开文件选择框
    const openFileModal = (id:string)=>{
      document.getElementById(id)?.click();
    }
    // 添加边界图层
    const addBorderLayer = (id:number)=>{
      if(!maps.map) return
      let layerInfo:MapLayerRequestInfo = {
        cellId:id,
        craft:"HaErBin-JBZ", // cement-修改工艺代码---已修改
        type:"border"
      }
      if(maps.map.getLayer(`${layerInfo.type}`)) maps.map.removeLayer(`${layerInfo.type}`)
      if(maps.map.getSource(`${layerInfo.type}`)) maps.map.removeSource(`${layerInfo.type}`)

      maps.map.addSource(`${layerInfo.type}`,{
        type: "raster",
        scheme:"tms",
        tiles: [
          `${config.map.geoServer}${layerInfo.craft}%3A${layerInfo.cellId}_${layerInfo.type}@EPSG%3A900913@png/{z}/{x}/{y}.png`
        ],
        tileSize: 256,
      })
      maps.map.addLayer({
        id: `${layerInfo.type}`,
        type: "raster",
        source: `${layerInfo.type}`,
        paint: {
          "raster-opacity": 1,
        },
      })
    }
    // 读取边界数据
    const readBorderFile = (cellId:number)=>{
      let inputDOM: any = document.getElementById("uploadBorderFile")
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader();
        reader.readAsText(files[0], "UTF-8");
        reader.onload = (e: any)=>{
          try{
            let fileStr = e.target.result
            let fileStrArr = fileStr.split(",,")

            coordinateTypeFormState.value.cellId = cellId
            coordinateTypeFormState.value.count = 0
            coordinateTypeFormState.value.first = new Array()
            coordinateTypeFormState.value.second = new Array()

            for (let i = 0; i < fileStrArr.length; i++) {
              let pointArr = fileStrArr[i].split(",")
              if (pointArr.length == 2) {
                coordinateTypeFormState.value.count++
                coordinateTypeFormState.value.first.push(parseFloat(pointArr[0]))
                coordinateTypeFormState.value.second.push(parseFloat(pointArr[1]))
              }
            }
            setBorder(coordinateType.value,(res:any)=>{
              if(res.data.count>=3){
                let minX = res.data.second[0]
                let maxX = res.data.second[0]
                let minY = res.data.first[0]
                let maxY = res.data.first[0]
                for (let i= 0; i< res.data.count; i++){
                  minX = minX > res.data.second[i] ? res.data.second[i] : minX
                  maxX = maxX < res.data.second[i] ? res.data.second[i] : maxX
                  minY = minY > res.data.first[i] ? res.data.first[i] : minY
                  maxY = maxY < res.data.first[i] ? res.data.first[i] : maxY
                }
                if(maps.map) {
                  maps.map.setZoom(16)
                  maps.map.jumpTo({center: new mapboxgl.LngLat((minY+maxY)/2, (minX+maxX)/2)})
                }
              }
            })
          }catch (e){
            message.warn("导入格式错误")
          }
        }
        inputDOM.value = "";
      }
    }
    // 获取边界
    const getBorder = (type:number = 1, cellId:number, callback:Function | null)=>{
      let url = type==1?"/common/findCellBorderByCellIdAB":"/common/findCellBorderByCellId"
      axios.post(url,
          {cellId:cellId}).then((res:any)=>{
        if(res.success){
          border.abBorder = new Array()
          border.wgsBorder = new Array()
          let borderList = new Array()
          for (let i = 0; i < res.data.borderCount; i++) {
            borderList.push({
              lon:res.data.first[i],
              lat:res.data.second[i],
            })
          }
          if(type == 1){
            border.abBorder = borderList
          }else if(type == 2){
            border.wgsBorder = borderList
          }
          if(callback) callback(res)
        }else{
          message.info(res.msg)
        }
      })
    }
    // 设置边界
    const setBorder = (type:number = 1,callback:Function | null = null)=>{
      let url = type==1?"/common/updateCellBorderByCellIdAB":"/common/updateCellBorderByCellId"
      axios.post(url,
          coordinateTypeFormState.value).then((res1:any)=>{
        if(res1.success){
          createTiledMap(coordinateTypeFormState.value.cellId).then((res2:any)=>{
            if(res2&&callback){
              callback(res1)
            }
            if(!res2) message.info("生成瓦片图失败")
          })
          message.info("导入成功")
        }else{
          message.info(res1.msg)
        }
      })
    }
    // 绘制边界瓦片  cement-修改接口---已修改
    const createTiledMap = (cellId:number)=>{
      return new Promise((resolve,reject)=>{
        axios.post("/jbzMap/reCreatBorder",
            qs.stringify({
              cellID:cellId
            }),{
              headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then((res:any)=>{
          axios.post("/jbzMap/reCreatReport",
              qs.stringify({
                cellID:cellId,
                workType:1,
              }),{
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
              })
          axios.post("/jbzMap/reCreatReport",
              qs.stringify({
                cellID:cellId,
                workType:2,
              }),{
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
              })
          resolve(res.success)
        })
      })
    }
    // 读取设计点数据
    const readPointFile = (cellId:number, input:string)=>{
      let inputDOM: any = document.getElementById(input)
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader();
        reader.readAsText(files[0], "UTF-8");
        reader.onload = (e: any)=>{
          let fileStr = e.target.result
          let fileStrArr = fileStr.split(",,")

          let data = {
            cellId:cellId,
            count:0,
            first:new Array<number>(),
            second:new Array<number>(),
            pointName: new Array<string>()
          }

          for (let i = 0; i < fileStrArr.length; i++) {
            let pointArr = fileStrArr[i].split(",")
            if (pointArr.length == 3) {
              data.count++

              let name = String(pointArr[0]).trim()
              let nameLength = name.length
              if(nameLength==0||nameLength>10){
                message.info("点位长度过短或过长")
                return
              }
              data.pointName.push(name)
              data.first.push(parseFloat(pointArr[1]))
              data.second.push(parseFloat(pointArr[2]))
            }
          }
          setDesignPoint(data)
        }
        inputDOM.value = "";
      }
    }
    // 设置设计点  cement-修改接口---已修改
    const setDesignPoint = (designData:any)=>{
      axios.post("/cement/saveDesignPoint",designData).then((res:any)=>{
        if(res.success){
          createTiledMap(designData.cellId)
          message.info("导入成功")
        }else{
          message.info(res.msg)
        }
      })
    }
    // 生成设计点 cement-修改接口---已修改
    const buildCementDesignPoint = (cellId: number)=>{
      axios.post("/cement/buildDesignPoint", {cellId: cellId, distance: cementDesignPointForm.value.distance}).then((res:any)=>{
        if(res.success){
          createTiledMap(cellId)
          message.info("生成成功")
        }else{
          message.info(res.msg)
        }
      })
    }
    // 下载设计点数据  cement-修改接口---已修改
    const downloadPointFile = (cellId:number)=>{
      axios.post("/cement/downloadDesignPoint", {cellId: cellId},
          {responseType: 'blob'}).then((res:any)=>{
            // 前端获取业务码，成功执行正常业务
            const link = document.createElement('a');
            link.target = "_blank";
            link.href = URL.createObjectURL(res); // 创建下载的链接
            link.download = `${props.cellInfo.cellName}.xlsx`; // 下载后文件名
            link.click(); // 点击下载
            URL.revokeObjectURL(link.href); // 释放掉blob对象
            document.body.removeChild(link); // 下载完成移除元素
          })
    }

    watch(()=>props.cellInfo,(newValue,oldValue)=>{
      setTimeout(()=>{
        getNorm(newValue.cellId)
        addBorderLayer(newValue.cellId)
        getBorder(2,newValue.cellId,(res:any)=>{
          if(res.data.borderCount>=3){
            let minX = res.data.second[0]
            let maxX = res.data.second[0]
            let minY = res.data.first[0]
            let maxY = res.data.first[0]
            for (let i= 0; i< res.data.borderCount; i++){
              minX = minX > res.data.second[i] ? res.data.second[i] : minX
              maxX = maxX < res.data.second[i] ? res.data.second[i] : maxX
              minY = minY > res.data.first[i] ? res.data.first[i] : minY
              maxY = maxY < res.data.first[i] ? res.data.first[i] : maxY
            }
            if(maps.map) {
              maps.map.setZoom(16)
              maps.map.jumpTo({center: new mapboxgl.LngLat((minY+maxY)/2, (minX+maxX)/2)})
            }
          }
        })
      },500)
    },{immediate: true})

    onMounted(()=>{
      initMap()
    })

    onBeforeUnmount(()=>{
      maps.map.remove()
    })

    return {
      showBorderModal,
      coordinateType,
      KindEnum,
      coordinateDict,
      cementDict,
      readBorderFile,
      openFileModal,
      ...toRefs(border),
      getBorder,

      norm, cementDesignPointForm,
      addVNorm,
      removeNorm,
      setNorm,
      readPointFile,
      buildCementDesignPoint,
      downloadPointFile
    }
  },
  props: {
    isShow: {
      type: Boolean,
      default: false
    },
    cellInfo: {
      type: Object,
      default: null
    }
  },
  components:{ DeleteOutlined, SModal }
})
</script>

<style scoped lang="scss">
.map-box {
  position: relative;
  flex: 1;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  #mapboxgl-box {
    display: flex;
    width: 100%;
    height: calc(100% - 6px);
    box-sizing: border-box;
  }
}
.form-box  {
  display: flex;
  flex-direction: column;
  margin-top: 20px;
  width: 100%;
  height: 503px;
  padding: 18px 30px 10px 30px;
  box-sizing: border-box;
  .set-header {
    font-size: 18px;
    font-weight: bold;
    color: #333333;
    padding-bottom: 10px;
    border-bottom: 1px solid #EDF0FB;
  }
  .set-form {
    flex: 1;
    width: 100%;
    > span {
      display: block;
      padding: 12px 0px 5px;
      font-size: 16px;
      font-weight: bold;
      color: #333333;
    }
    ::v-deep .ant-input-number {
      width: 150px;
    }
    ::v-deep .ant-select{
      width: 177px;
    }
    ::v-deep label {
      display: block;
      width: 110px;
      color: #666666;
    }
    .item-width {
      ::v-deep label {
        width: 160px;
      }
    }
    ::v-deep .button-box{
      float: right;
      button{
        margin-left: 8px;
      }
    }
    .right-item{
      float: right;
      ::v-deep button{
        margin-left: 18px;
      }
    }
    .standard {
      display: flex;
      width: 100%;
      height: 220px;
      .left-form {
        display: flex;
        flex-direction: column;
        width: 560px;
        height: 160px;
        ::v-deep .ant-form-item {
          //margin-bottom: 15px;
        }
      }
      .right-table {
        display: flex;
        flex-direction: column;
        flex: 1;
        height: 100%;
        >span {
          font-size: 14px;
          color: #666666;
        }
        ::v-deep .ant-empty {
          margin: 14px 0;
        }
        .button-box{
          display: flex;
          justify-content: flex-end;
          width: 100%;
          height: 60px;
          padding-top: 14px;
          padding-right: 16px;
          box-sizing: border-box;
        }
      }
    }
  }
}
</style>